#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "serialport/qscom.h"
#include <QMainWindow>
#include <QSettings>
#include <QAbstractNativeEventFilter>
#include <QComboBox>
#include <USB_monitor.h>
#include <QLabel>
#include <QListWidget>
#include "filelog.h"
#include <settingswindow.h>

QT_BEGIN_NAMESPACE
namespace Ui
{
class MainWindow;
}
QT_END_NAMESPACE

#ifndef LINUX_USB_MONITOR_MOD
class MainWindow : public QMainWindow, public QAbstractNativeEventFilter
#else
class MainWindow : public QMainWindow
#endif
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

signals:
#ifdef LINUX_USB_MONITOR_MOD
    void sigUSBMonitorExec();
#endif

private slots:
    /* USB Monitor thread slots */
    void slotUSBDetected(QString info);
    void slotUSBRefresh();
    void deleteSeedSlot();

    void slotSettingsValid(SettingsWindow::settingsWindow &sw);

    void slotSpDataReceive(QString name, QString str);
    void on_newTab_triggered();
    void on_show_Tool_Bar_toggled(bool arg1);
    void on_tabWidget_tabCloseRequested(int index);
    void on_tabWidget_currentChanged(int index);
    void on_save_triggered();
    void on_refresh_triggered();
    void on_openPort_triggered(bool checked);
    void on_pushButton_sendData_clicked();
    void on_radioButton_rec_clicked(bool checked);
    void on_noReceive_triggered(bool checked);
    void on_newSession_triggered();
    void on_save_2_triggered();
    void on_saveAll_triggered();
    void on_eraseTextEdit_triggered();
    void on_showSettingsWin_triggered(bool checked);
    void on_tabPre_triggered();
    void on_tabNext_triggered();
    void on_closeSession_triggered();
    void on_linuxMode_triggered(bool checked);
    void on_recCached_triggered(bool checked);
    void on_comboBox_endChar_currentIndexChanged(int index);
    void on_checkBox_echo_clicked(bool checked);
    void on_checkBox_showTime_clicked(bool checked);

    void on_listWidget_sendRecords_customContextMenuRequested(const QPoint &pos);

    void on_comboBox_port_currentIndexChanged(int index);

    void on_listWidget_sendRecords_itemClicked(QListWidgetItem *item);

    void on_action_sendList_triggered(bool checked);

    void on_action_settingsWindow_triggered();

    void on_action_logToFile_triggered(bool checked);

private:
    Ui::MainWindow *ui;
    qscoms qsc;
    using listSpInfo   = QList<QSerialPortInfo>;
    QString uiConfName = "ui_config.json";
    listSpInfo spsInfo;
    QSettings settings;
#ifdef LINUX_USB_MONITOR_MOD
    /* Thread */
    QThread *usbMonitor;
    USBMonitor *usbmThread;
    QTimer *timer; /* 检测到USB设备时，需要延迟读取信息，否则可能会读取不到设备的描述信息 */
#endif

    QLabel *labelPortStatusIco;
    QLabel *labelPortName;

    QList<qscom::BaudRate> baudRate;
    QList<qscom::DataBits> dataBits;
    QList<qscom::Parity> parity;
    QList<qscom::StopBits> stopBits;
    QList<qscom::FlowControl> flowCtrl;
    QList<QString> endChar;

    QStringList icon_fruit{"apple.png", "grapes.png", "durian.png", "orange-juice.png", "strawberry.png", "watermelon.png", "bananas.png"};

    /**
     * @brief The PageInfo struct
     * @details 存储每个串口的设置，用于切换页面的时候进行恢复
     */
    struct PageInfo {
        QString name;
        qscoms::PortConfig pc = {qscom::Baud115200, qscom::Data8, qscom::NoParity, qscom::OneStop,
                                 qscom::NoFlowControl};
        QString endChar       = "\n";
        bool showTimestamp    = false;
        bool recStop          = false;
        bool echo             = false;
        bool open             = false;
        bool linuxMode        = false;
        bool recCached        = false;

        QStringList sendRecords;   // 发送记录

        FileLog *fLog = nullptr;
    };
    QList<PageInfo> pInfo;
    bool isSendRecordSelect = false;
    const int RECORD_LIST_MAX_SZE = 30;

    SettingsWindow::settingsWindow globalSettings = {.log{true, ".", 1024*1024*1024, false, true}};
    SettingsWindow *settingsWin;

    void uiInit();
    void setPageInfo(int index);
    void getPageInfo(int index);
    int newTab();
    void deleteTab(int index);
    void setButtonOpen(bool open);
    QString getPortName(int index);
    int getPortIndex(const QString &name);
    PageInfo * getPageInfo(const QString &name);
    void clockUi(bool clock);
    void stopRec(bool stop);
    void portValid();
    void refreshTabIcon();
    void dataRecWidgetAppend(int index, const QString &data);
    void addSendRecord(int index, const QString &data);
    void removeOtherPort();
    void resetComboBoxWidth(QComboBox *cb);
    void statusBarInit();
    void statusBarSetPortInfo(bool connected, const QString &portInfo);
    void statusBarSetPortInfo();

    void saveUiConfig();
    void readUiConfig();
    void saveUiWindow();
    int restoreUiWindow();

protected:
    virtual void closeEvent(QCloseEvent *event);
//    virtual void keyPressEvent(QKeyEvent *event);
    virtual bool eventFilter(QObject *target, QEvent *event);
#ifndef LINUX_USB_MONITOR_MOD
    virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
#endif
};
#endif // MAINWINDOW_H
